#pragma once

#include <iostream>
#include <string>
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <DxErr.h>

#include "Timer.h"
#include "Camera.h"
#include "Mesh.h"

#define VERSION_MAJOR 0
#define VERSION_MINOR 0
#define VERSION_REVISION 2

namespace PGE2D
{
	extern bool gameover;
	extern bool game_preload();
	extern bool game_init( HWND );
	extern void game_update();
	extern void game_end();

	extern void game_render3d();

	class Engine {
	private:
		int p_versionMajor, p_versionMinor, p_revision;
		int p_screenWidth, p_screenHeight;
		int p_colorDepth;
		bool p_fullScreen, p_pauseMode;
		
		//Windows & DirectX stuff
		HWND p_windowHandle;
		LPDIRECT3D9 p_d3d;
		LPDIRECT3DDEVICE9 p_device;
		LPDIRECT3DSURFACE9 p_backbuffer;
		LPD3DXSPRITE p_sprite_handler;
		D3DCOLOR p_ambientColor;

		//Timer objects
		Timer p_coreTimer;
		long p_frameCount_core, p_frameRate_core;

		Timer p_realTimer;
		long p_frameCount_real, p_frameRate_real;

		bool p_maximizeProcessor;

	public:
		Engine();
		virtual ~Engine();

		int Init( int width, int height, int colorDepth, bool fullscreen );
		void Close();
		void Update();
		void Shutdown();

		//drawing functions
		void ClearScene(D3DCOLOR color);
		void SetDefaultMaterial();
		void SetAmbient( D3DCOLOR colorValue );
		int RenderStart();
		int RenderStop();
		void SetIdentity();

		//Just making this public
		std::string p_appTitle;
		
		//accessors and mutators and all that
		LPDIRECT3DDEVICE9 getDevice() { return p_device; }
		LPDIRECT3DSURFACE9 getBackBuffer() { return p_backbuffer; }
		LPD3DXSPRITE getSpriteHandler() { return p_sprite_handler; }

		void setWindowHandle( HWND hWnd ) { p_windowHandle = hWnd; }
		HWND getWindowHandle( void ) { return p_windowHandle; }

		bool isPaused() { return p_pauseMode; }
		void setPaused(bool p) { p_pauseMode = p; }

		std::string getAppTitle() { return p_appTitle; }
		void setAppTitle(std::string name) { p_appTitle = name; }

		int getScreenWidth() { return p_screenWidth; }
		void setScreenWidth(int w) { p_screenWidth = w; }

		int getScreenHeight() { return p_screenHeight; }
		void setScreenHeight( int h ) { p_screenHeight = h; }

		int getColorDepth() { return p_colorDepth; }
		void setColorDepth(int d) { p_colorDepth = d; }

		bool getFullScreen() { return p_fullScreen; }
		void setFullScreen(bool f) { p_fullScreen = f; } 

		bool getMaximizeProcessor() { return p_maximizeProcessor; }
		void setMaximizeProcessor(bool value) { p_maximizeProcessor = value; }

		std::string getVersionText();
	};
}

extern PGE2D::Engine *g_engine;